﻿///////////////////////////////////////////////////////////////////////////////
// Name:        mainApp.cpp
// Purpose:     步进电机驱动程序
// Author:      dbian
// Modified by:
// Created:     2011-7-05
// Copyright:   (C) Copyright 2011, Dbian, All Rights Reserved.
// Licence:     wxWindows Library Licence, Version 3.1
///////////////////////////////////////////////////////////////////////////////
//先决
#include "const.h"//
#include "curve.h"
#include "inisetter.h"
#include "devices.h"

#include "mainApp.h"

//无关联
#include "dlgQuery.h"



// -- application --

IMPLEMENT_APP(MainApp)



//给新消息取值，并申明
DEFINE_EVENT_TYPE(EVT_CLEAR_CHART)
DEFINE_EVENT_TYPE(EVT_ADD_RED)
DEFINE_EVENT_TYPE(EVT_ADD_BLUE)
DEFINE_EVENT_TYPE(EVT_ADD_DATA)
DEFINE_EVENT_TYPE(EVT_ADD_STATUS_2)
DEFINE_EVENT_TYPE(EVT_ADD_STATUS_3)

typedef void (wxEvtHandler::*UserEventHandler)(UserEvent&);

#define EVT_clearChart(fn) DECLARE_EVENT_TABLE_ENTRY( EVT_CLEAR_CHART, 0, -1, \
    (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) \
	wxStaticCastEvent( UserEventHandler, & fn ), (wxObject *) NULL ),
#define EVT_addRed(fn)	DECLARE_EVENT_TABLE_ENTRY( EVT_ADD_RED, 0, -1, \
(wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) \
	wxStaticCastEvent( UserEventHandler, & fn ), (wxObject *) NULL ),
#define EVT_addBlue(fn) \
    DECLARE_EVENT_TABLE_ENTRY( EVT_ADD_BLUE, 0, -1, \
    (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) \
	wxStaticCastEvent( UserEventHandler, & fn ), (wxObject *) NULL ),
#define EVT_addData(fn) \
    DECLARE_EVENT_TABLE_ENTRY( EVT_ADD_DATA, 0, -1, \
    (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) \
	wxStaticCastEvent( UserEventHandler, & fn ), (wxObject *) NULL ),
#define EVT_Status_2(fn) \
    DECLARE_EVENT_TABLE_ENTRY( EVT_ADD_STATUS_2, 0, -1, \
    (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) \
	wxStaticCastEvent( UserEventHandler, & fn ), (wxObject *) NULL ),
#define EVT_Status_3(fn) \
    DECLARE_EVENT_TABLE_ENTRY( EVT_ADD_STATUS_3, 0, -1, \
    (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) \
	wxStaticCastEvent( UserEventHandler, & fn ), (wxObject *) NULL ),


//
bool MainApp::OnInit()
{

	wxFrame* frame = new MainFrame(NULL,
		wxID_ANY,
		TITLE,
		wxDefaultPosition,
		wxSize(800, 600));
	SetTopWindow(frame);
	frame->Show();

	return true;
}

BEGIN_EVENT_TABLE(MainFrame, wxFrame)
	
//menu
	EVT_MENU(XRCID("menuStart"),MainFrame::onStart)
	EVT_MENU(XRCID("menuPause"),MainFrame::onPause)
	EVT_MENU(XRCID("menuStop"),MainFrame::onStop)
	EVT_MENU(XRCID("menuExit"),MainFrame::onExit)
	EVT_MENU(XRCID("menuHelp"),MainFrame:: onHelp)
	EVT_MENU(XRCID("menuAbout"),MainFrame:: onAbout)
	EVT_MENU(XRCID("menuDebug"),MainFrame:: onDebug)
	EVT_MENU(XRCID("menuSave"),MainFrame:: onSave)
	EVT_MENU(XRCID("menuPort"),MainFrame:: onPort)
//自定义
	EVT_clearChart(MainFrame::clearChart)
	EVT_addRed(MainFrame::addRed)
	EVT_addBlue(MainFrame::addBlue)
	EVT_addData(MainFrame::addData)
	EVT_Status_2(MainFrame::UpdateStatus2)
	EVT_Status_3(MainFrame::UpdateStatus3)


END_EVENT_TABLE()


	MainFrame::MainFrame(wxWindow* parent,
	wxWindowID id,
	const wxString& title,
	const wxPoint& pos,
	const wxSize& size,
	long style)
	: wxFrame(parent, id, title, pos, size, style)
{
	//加载资源
	init_res();
	SetMenuBar(wxXmlResource::Get()->LoadMenuBar(wxT("menu")));

	plot=new chart(this,-1);
	wxBoxSizer*sz=new wxBoxSizer(wxVERTICAL);
	sz->Add(plot,1,wxALL|wxEXPAND,5);
	this->SetSizer(sz);
	this->Layout();
	plot->setTitle(wxT("步进电机-锁相/门积分器..."));
	plot->setXLabel(wxT("步数"));
	plot->setYLabel(wxT("电压/伏"));
	/*plot->addred(11,22);
	plot->addred(33,44);
	plot->addred(33,11);
	plot->addblue(1,-6);*/
	//0，状态显示，进度
	CreateStatusBar( 3 );

	//读取配置
	setupIni();

	//其他数据初始化
	queryPara=wxT("");
	state=state_stop;
	wxLog::SetTimestamp(wxT("%Y-%m-%d %H:%M:%S"));
	wxLog::SetLogLevel(wxLOG_Debug);
#ifdef _DEBUG
	logw=new wxLogWindow(0,L"debug window",1);
	 
#else
	logw=new wxLogWindow(0,L"debug window",0);
#endif
	wxLogMessage(L"Log开始");
	wxLog::Suspend();
	//端口打开
	dev.app=this;
	dev.pflag=&state;
	dev.pPara=&queryPara;
	dev.openMotorPort(comM+1);
	dev.openReaderPort(comR+1);
	
	//clearChart();

}


void MainFrame::onStart(wxCommandEvent&WXUNUSED(e))
{
	if(state==state_run)
	{
		msg(L"正在运行，请等待停止");
		return;
	}
	
	dlgQuery dlg(this,&queryPara);
	int hr=dlg.ShowModal();
	/*msg(getArray(0,queryPara)[1]);
	msg(getArray(1,queryPara)[0]);*/
	if(hr==wxID_OK)
	{
		dev.start();
		state=state_run;
	}
}
void MainFrame::onPause(wxCommandEvent&WXUNUSED(e))
{
	if(state==state_run)
		state=state_pause;
	else if(state==state_pause)
		state=state_run;
}
void MainFrame::onStop(wxCommandEvent&WXUNUSED(e))
{
	state=state_stop;
}
void MainFrame::onExit(wxCommandEvent&WXUNUSED(e))
{
	this->Close();
}
void MainFrame::onHelp(wxCommandEvent&WXUNUSED(e))
{
}
void MainFrame::onSave(wxCommandEvent&WXUNUSED(e))
{
	wxFileDialog dlg(this,L"保存实验数据",wxEmptyString,wxEmptyString,\
		L"data files (*.txt;*.dat)|*.txt;*.dat",\
		wxFD_SAVE |wxFD_OVERWRITE_PROMPT |wxFD_CHANGE_DIR);
	if(dlg.ShowModal()==wxID_OK)
	{
		wxString path=dlg.GetPath();
		wxFile fp(path,wxFile::write);
		wxString str;
		if(!dev.red.empty() && dev.blue.empty())
		{
			for(unsigned int k=0;k!=dev.red.size();k++)
			{
				str.Printf(L"%d\t%.8f\r\n",(int)(dev.red[k]->x),dev.red[k]->y);
				fp.Write(str);
			}
		}
		else if(dev.red.empty() && !dev.blue.empty())
		{
			for(unsigned int k=0;k!=dev.blue.size();k++)
			{
				str.Printf(L"%d\t\t%.8f\r\n",(int)(dev.blue[k]->x),dev.blue[k]->y);
				fp.Write(str);
			}
		}
		else if(!dev.red.empty() && !dev.blue.empty())
		{
			for(unsigned int k=0;k!=dev.blue.size();k++)
			{
				str.Printf(L"%d\t%.8f\t%.8f\r\n",(int)(dev.blue[k]->x),dev.red[k]->y,dev.blue[k]->y);
				fp.Write(str);
			}
		}
			
	}

}
void MainFrame::onAbout(wxCommandEvent&WXUNUSED(e))
{
	wxDialog dlg;
    if ( wxXmlResource::Get()->LoadDialog(&dlg, this, wxT("About")) )
        dlg.ShowModal();
	
}
void MainFrame::onDebug(wxCommandEvent&WXUNUSED(e))
{
	debugMode=!debugMode;
	if(!debugMode)
		wxLog::Suspend();
	else
		wxLog::Resume();
}
void MainFrame::onPort(wxCommandEvent&WXUNUSED(e))
{
	dlgSelComm dlg(this,&comM,&comR);

	if(dlg.ShowModal()==wxID_OK)
	{
		//存入配置
		wchar_t set[100];
		wsprintf(set,L"%d",comM);
		ini.set(L"App Port Settings",L"comMotor",set);
		wsprintf(set,L"%d",comR);
		ini.set(L"App Port Settings",L"comReader",set);
		//打开端口
		dev.closeMotorPort();
		dev.closeReaderPort();
		dev.openMotorPort(comM+1);
		dev.openReaderPort(comR+1);
	}
}
//cust event
void MainFrame::clearChart(UserEvent&WXUNUSED(e))
{
	plot->clearAll();
}
void MainFrame::addRed(UserEvent&e){
	
	plot->addred(e.p1.x,e.p1.y);
}
void MainFrame::addBlue(UserEvent&e){
	plot->addblue(e.p2.x,e.p2.y);
}
void MainFrame::addData(UserEvent&e)
{
	plot->setData(e.red,e.blue);
}
void MainFrame::UpdateStatus2(UserEvent&e)
{
	this->GetStatusBar()->SetStatusText(e.msgg,1);
}
void MainFrame::UpdateStatus3(UserEvent&e)
{
	this->GetStatusBar()->SetStatusText(e.msgg,2);
}
//entry
//DEFINE_EVENT_TYPE(EVT_CLEAR_CHART)
//DEFINE_EVENT_TYPE(EVT_ADD_RED)
//DEFINE_EVENT_TYPE(EVT_ADD_BLUE)
//DEFINE_EVENT_TYPE(EVT_ADD_DATA)
//DEFINE_EVENT_TYPE(EVT_ADD_STATUS_2)
//DEFINE_EVENT_TYPE(EVT_ADD_STATUS_3)
void MainFrame::clearChart()
{
	UserEvent e(EVT_CLEAR_CHART);//传送副本，所以需要clone
	this->AddPendingEvent(e);
}
void MainFrame::addRed(double x,double y){
	UserEvent e(EVT_ADD_RED);
	e.p1.x=x;
	e.p1.y=y;
	this->AddPendingEvent(e);
}
void MainFrame::addBlue(double x,double y){
	UserEvent e(EVT_ADD_BLUE);
	e.p2.x=x;
	e.p2.y=y;
	this->AddPendingEvent(e);
}
void MainFrame::addData(std::vector<Point*>&red,std::vector<Point*>&blue)
{
	UserEvent e(EVT_ADD_DATA);
	e.red=&red;//直接拷贝一个副本
	e.blue=&blue;
#ifdef _DEBUG
	wxLogMessage(L"发送重绘事件");
#endif

	this->AddPendingEvent(e);
}
void MainFrame::Log2(const wxString&msgs )
{
	UserEvent e(EVT_ADD_STATUS_2);
	e.msgg=msgs;
	this->AddPendingEvent(e);
}
void MainFrame::Log3(const wxString&msgs)
{
	UserEvent e(EVT_ADD_STATUS_3);
	e.msgg=msgs;
	this->AddPendingEvent(e);
}

void MainFrame::setupIni()
{
	ini.setpath(INI);
	//置入默认
				//端口配置
	std::map<const wchar_t*,const wchar_t*> m;
	m[L"comMotor"]=L"0";
	m[L"comReader"]=L"1";
	ini.setdefault(L"App Port Settings",m);
	//读取配置
	wchar_t set[100];
	ini.get(L"App Port Settings",L"comMotor",set);
	comM=_wtoi(set);
	ini.get(L"App Port Settings",L"comReader",set);
	comR=_wtoi(set);
}
